package pl.edu.agh.inpema.components.receivers.phpBB2Receiver;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.htmlparser.util.ParserException;

import pl.edu.agh.inpema.components.receivers.phpBB2Receiver.connector.ConnectionException;
import pl.edu.agh.inpema.components.receivers.phpBB2Receiver.model.Post;
import pl.edu.agh.inpema.components.receivers.phpBB2Receiver.model.Subject;
import pl.edu.agh.inpema.components.receivers.phpBB2Receiver.model.Topic;
import pl.edu.agh.inpema.components.receivers.phpBB2Receiver.util.Logger;
import pl.edu.agh.inpema.core.components.ReceiverUtil;
import pl.edu.agh.inpema.core.configuration.ConfigurationException;
import pl.edu.agh.inpema.core.model.Message;
import pl.edu.agh.inpema.core.model.Receiver;

public class PhpBB2Receiver extends Thread implements Receiver {
	
	private static final String POST_BODY_TYPE_TEXT = "text";
	private static final String POST_BODY_TYPE_HTML = "html";
	
	private ReceiverUtil receiverUtil;
	
	private boolean isRunning = false;
	private boolean shouldRun = false;
	private boolean wasError = false;
	
	private String url;
	private String login;
	private String password;
	private String dateFormat;
	private long sleepTime;
	private boolean asHtml = false;

	private static final String[] messageFieldTypes = {
		FIELD_DATE, FIELD_TEXT
	};
	
	public void startGathering() {
		this.shouldRun = true;
		this.isRunning = true;
		this.start();
	}
	
	public boolean stopGathering() {
		this.shouldRun = false;
		return this.wasError;
	}

	public boolean isGatheringRunning() {
		return this.isRunning;
	}
	
	public void setReceiverUtil(ReceiverUtil receiverUtil) {
		this.receiverUtil = receiverUtil;
	}
	
	public ReceiverUtil getReceiverUtil() {
		return this.receiverUtil;
	}
	
	public String[] getMessageFieldTypes() {
		return messageFieldTypes;
	}
	
	public void setUrl(String url) {
		this.url = url;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setDateFormat(String dateFormat) {
		this.dateFormat = dateFormat;
	}

	public void setSleepTime(long sleepTime) {
		this.sleepTime = sleepTime;
	}
	
	public void setPostBodyType(String type) throws ConfigurationException {
		if (POST_BODY_TYPE_TEXT.equals(type.toLowerCase())) {
			this.asHtml = false;
		} else if (POST_BODY_TYPE_HTML.equals(type.toLowerCase())) {
			this.asHtml = true;
		} else {
			throw new ConfigurationException("'"+type+"' is not supported type of postBodyType parameter");
		}		
	}
	
	public void run() {
		long startTime = System.currentTimeMillis();
		try {
			
			ForumAnalyzer analyzer = new ForumAnalyzer(this.url, this.login, this.password, this.dateFormat, this.asHtml, this.sleepTime);
			
			List<Subject> subjects = analyzer.getAllSubjects();
			Iterator<Subject> subjectsIterator = subjects.iterator();
			int subjectNumber = 1;
			while (subjectsIterator.hasNext() && this.shouldRun) {
				Subject subject = subjectsIterator.next();
				
				Logger.logMesage("=== analyzying: "+subject.getSubject()+" ("+subjectNumber+" of "+subjects.size()+") ===");
				subjectNumber++;
				
				List<Topic> topics = analyzer.getAllTopicsFromSubjectAddress(subject.getAddress());
				//Logger.logMesage("    ["+topics.size()+" topics]");
				
				Iterator<Topic> topicsIterator = topics.iterator();
				int topicNumber = 1;
				while(topicsIterator.hasNext() && this.shouldRun) {
					
					Topic topic = topicsIterator.next();
					
					Logger.logMesageWithoutNewLine("    topic "+topicNumber+" of "+topics.size()+": "+topic.getSubject());
					topicNumber++;
					List<Post> posts = analyzer.getAllPostsFromTopicAddress(topic.getAddress());
					Logger.logMesageWithoutNewLine(" ["+posts.size()+" posts] ... ");
					
					Iterator<Post> postsIterator = posts.iterator();
					while(postsIterator.hasNext() && this.shouldRun) {
						Post post = postsIterator.next();
						Map<String, String> messageFields = new HashMap<String, String>();
						messageFields.put(Message.FIELD_DATE, ""+post.getDate());
						messageFields.put(Message.FIELD_TEXT, post.getBody());
						this.receiverUtil.addMessage(post.getLogin(), messageFields);
					}
					
					Logger.logMesage("done");
				}
			}
		} catch (ParserException e) {
			e.printStackTrace();			
		} catch (ConnectionException e) {
			e.printStackTrace();
		}
		long endTime = System.currentTimeMillis();
		
		long durationTime = endTime - startTime;
		double durationTimeSec = ((double) durationTime) / 1000;
		
		Logger.logMesage("SYSTEM DONE IN "+durationTimeSec+" sec");
		
		this.isRunning = false;
	}
}
